﻿using Cxuu.Common;
using Cxuu.Models;
using Cxuu.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text.Json;
using System.Threading.Tasks;

namespace Cxuu.Service
{
    [AppService]
    public class ArticleCateService
    {
        private readonly ArticleCateRepository articleCateDal;
        private readonly ArticleRepository articleRepository;

        private readonly AdminUserDeptService _AdminUserDeptService;
        private readonly ICacheManager _cacheManager;
        private readonly string cacheKey;
        public ArticleCateService(ArticleCateRepository articleCateRepository, ArticleRepository article,
           ICacheManager cacheManager, AdminUserDeptService adminUserDeptService)
        {
            _cacheManager = cacheManager;
            articleCateDal = articleCateRepository;
            articleRepository = article;

            cacheKey = CacheConst.CACHE_KEY_ARTICLECATE + "all";
            _AdminUserDeptService = adminUserDeptService;
        }

        /// <summary>
        /// 全部列表 缓存
        /// </summary>
        /// <returns></returns>
        public async Task<List<ArticleCate>> GetAllAsync()
        {
            List<ArticleCate> cate = _cacheManager.Get<List<ArticleCate>>(cacheKey);
            if (cate == null)
            {
                cate = await articleCateDal.GetAllListAsync("Sort asc");
                _cacheManager.Set(cacheKey, cate, TimeSpan.FromDays(10));
            }
            return cate;
        }


        /// <summary>
        /// 根据 CID 获取 一条栏目缓存数据
        /// </summary>
        /// <returns></returns>
        public async Task<ArticleCate> GetInfo(int cid)
        {
            List<ArticleCate> cates = await GetAllAsync();
            return cates.FirstOrDefault(a => a.Id == cid);
        }



        public async Task<object> InsertAsync(ArticleCate articleCate)
        {
            _cacheManager.Remove(cacheKey);
            return await articleCateDal.InsertAsync(articleCate);
        }

        public async Task<int> UpdateAsync(ArticleCate articleCate)
        {
            _cacheManager.Remove(cacheKey);
            return await articleCateDal.UpdateAsync(articleCate);
        }

        public async Task<int> DeleteByPriKeyAsync(int id)
        {
            Article isArticleHave = await articleRepository.GetArticleByCidAsync(id);
            if (isArticleHave.Id > 0)
                return -1;
            _cacheManager.Remove(cacheKey);
            return await articleCateDal.DeleteByPriKeyAsync(id);
        }

        /// <summary>
        /// 根据权限获取栏目列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<ArticleCate>> CateRoleListAsync(IEnumerable<int> cids, int type = 0)
        {
            List<ArticleCate> cates = await GetAllAsync();
            if (cids == null)
            {
                return cates.Where(o => o.Type == type).ToList();
            }

            List<ArticleCate> newCates = new();
            
            foreach (int cid in cids)
            {
                ArticleCate cate = new();
                if (type == 0)
                {
                    cate = cates.FirstOrDefault(o => o.Id == cid);
                }
                else
                {
                    cate = cates.FirstOrDefault(o => o.Type == type && o.Id==cid);
                }

                if (cate != null)
                {
                    newCates.Add(cate);
                }
            }
            //Console.WriteLine(newCates.Count);
            return newCates;
        }

        //获取当前用户部门的栏目权限信息
        public async Task<IEnumerable<int>> GetRoleChannlAsync(int deptId)
        {
            AdminUserDept adminUserDept = await _AdminUserDeptService.GetInfo(deptId);
            IEnumerable<string> role = JsonSerializer.Deserialize<IEnumerable<string>>(adminUserDept.ArticleCateRole);
            return role.Select(x => Convert.ToInt32(x));
        }

        public async Task<IEnumerable<ArticleCate>> CategoryListAsync(int deptId,int gid, int type = 0)
        {
            if (gid != 1)
            {
                IEnumerable<int> cateIdChannl = await GetRoleChannlAsync(deptId);
                return await CateRoleListAsync(cateIdChannl, type);
            }
            else
            {
                return await CateRoleListAsync(null, type);
            }
        }

        public async Task<IEnumerable<ViewArticleCate>> GetArticleCateListAsync(UserInfo adminUser, int role = 0)
        {
            List<ArticleCate> cates;
            if (role > 0)
            {
                if (adminUser.Gid == 1)
                {
                    cates = await GetAllAsync();
                }
                else
                {
                    IEnumerable<int> cateIdChannl = await GetRoleChannlAsync(adminUser.DeptId);
                    cates = await CateRoleListAsync(cateIdChannl);
                }
            }
            else
            {
                cates = await GetAllAsync();
            }
            return cates.AsCateListItems();//导出带 封装数据
        }

        /// <summary>
        /// 管理列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<ViewArticleCate>> GetCategorys()
        {
            return await GetCates(0, await GetAllAsync());
        }


        /// <summary>
        /// 递归树
        /// </summary>
        /// <param name="pid">父级Id</param>
        /// <param name="cates">数据源</param>
        /// <returns></returns>
        private async Task<List<ViewArticleCate>> GetCates(int pid, List<ArticleCate> cates = null)
        {
            var parent = cates.Where(P => P.Pid == pid);
            List<ViewArticleCate> lists = new();
            foreach (var item in parent)
            {
                ViewArticleCate Childer = new()
                {
                    Id = item.Id,
                    Title = item.Name,
                    Type = item.Type,
                    ObjectId1 = item.ObjectId1,
                    ObjectId2 = item.ObjectId2,
                    Ico = item.Ico,
                    Sort = item.Sort,
                    Num = item.Num,
                };
                Childer.Children = await GetSon(Childer, cates);
                if (Childer.Children != null)
                {
                    Childer.HaveChild = true;
                    Childer.Open = true;
                }
                lists.Add(Childer);
            }
            async Task<List<ViewArticleCate>> GetSon(ViewArticleCate cates, List<ArticleCate> sonCates = null)
            {
                if (!sonCates.Exists(x => x.Pid == cates.Id))
                {
                    return null;
                }
                else
                {
                    return await GetCates(cates.Id, sonCates);
                }
            }
            return lists.OrderBy(o => o.Sort).ThenBy(o => o.Id).ToList();
        }
    }
}
